package com.example.myweb.Controller.Auth;

import com.example.myweb.Common.ApiResponse;
import com.example.myweb.Domain.Entity.User;
import com.example.myweb.Dto.*;
import com.example.myweb.Dto.Auth.ForgotPasswordRequestDTO;
import com.example.myweb.Dto.Auth.LoginRequestDTO;
import com.example.myweb.Dto.Auth.RegisterRequestDTO;
import com.example.myweb.Dto.Auth.ResetPasswordRequestDTO;
import com.example.myweb.Dto.User.UserProfileResponseDTO;
import com.example.myweb.Dto.User.UserProfileUpdateRequestDTO;
import com.example.myweb.Exception.CustomException;
import com.example.myweb.Repository.JpaRepository.UserRepository;
import com.example.myweb.Security.JwtUtil;
import com.example.myweb.Service.Auth.*;
import com.example.myweb.Service.JwtBlacklistService;

import com.example.myweb.Vo.Auth.AuthResponseVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.lang.Nullable;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.Date;
import java.util.List;

@CrossOrigin
@RestController
@RequestMapping("/user") // 定义基础路径
public class AuthController {

    @Autowired
    private AuthService authService;

    @Autowired
    private FeedService feedService;

    @Autowired
    private UserService userService;
    @Autowired
    private UserRepository userRepository;

    @Autowired
    private JwtUtil jwtUtil;
    @Autowired
    private JwtBlacklistService jwtBlacklistService;

    @Autowired
    private CollectionService collectionService;
    @Autowired
    private FollowService followService;
    /**
     * 用户注册接口
     * POST /user/register
     */
    @PostMapping("/register")
    public ResponseEntity<ApiResponse<AuthResponseVO>> registerUser(@Valid @RequestBody RegisterRequestDTO request) {
        AuthResponseVO response = authService.register(request);
        return ResponseEntity.ok(ApiResponse.success(response, "注册成功。"));
    }

    /**
     * 用户登录接口
     * POST /user/login
     */
    @PostMapping("/login")
    public ResponseEntity<ApiResponse<AuthResponseVO>> loginUser(@Valid @RequestBody LoginRequestDTO request) {
        AuthResponseVO response = authService.login(request);
        return ResponseEntity.ok(ApiResponse.success(response, "登录成功。"));
    }

    @PostMapping("/logout")
    public ResponseEntity<ApiResponse<String>> logout(HttpServletRequest request) {
        String authorizationHeader = request.getHeader("Authorization");
        if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
            String token = authorizationHeader.substring(7);
            System.out.println("Logout request received with token: " + token);

            // 首先，验证 token 是否有效（签名、未过期等）
            if (jwtUtil.validateToken(token)) { // 现在通过注入的实例调用
                Date expirationDate = jwtUtil.extractExpiration(token);

                long currentTime = System.currentTimeMillis();
                long remainingTimeInSeconds = (expirationDate.getTime() - currentTime) / 1000;

                // 只有当 token 尚未过期时才加入黑名单
                if (remainingTimeInSeconds > 0) {
                    // ****** 修改这里：通过注入的实例调用非静态方法 ******
                    jwtBlacklistService.blacklistToken(token, remainingTimeInSeconds);
                    System.out.println("JWT已成功加入黑名单，剩余有效期: " + remainingTimeInSeconds + "秒。");
                } else {
                    System.out.println("尝试将已过期JWT加入黑名单，跳过。");
                }
            } else {
                // 如果 token 验证失败（例如签名无效），则不加入黑名单
                System.out.println("尝试将无效JWT加入黑名单，跳过。");
            }
        } else {
            System.out.println("登出请求未携带有效Bearer Token。");
        }

        // 清除Spring Security上下文中的认证信息
        SecurityContextHolder.clearContext();

        // 登出成功响应
        return ResponseEntity.ok(ApiResponse.success("登出成功。", "Logout successful."));
    }

    // 辅助方法：获取当前认证用户
    private User getCurrentAuthenticatedUser() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication == null || !authentication.isAuthenticated()) {
            throw new CustomException("User not authenticated."); // 或者更具体的错误
        }
        // 如果你的User实现了UserDetails，可以直接转型
        if (authentication.getPrincipal() instanceof User) {
            return (User) authentication.getPrincipal();
        }
        // 如果principal不是User类型，可能需要从userRepository中加载
        // 例如：String username = authentication.getName();
        // return userRepository.findByEmail(username).orElseThrow(() -> new CustomException("User not found"));
        throw new CustomException("Invalid user principal type.");
    }


    /**
     * 获取当前用户的个人资料
     * GET /user/me
     */
    @GetMapping("/me")
    public ResponseEntity<ApiResponse<UserProfileResponseDTO>> getUserProfile() {
        User currentUser = getCurrentAuthenticatedUser();

        UserProfileResponseDTO profile = new UserProfileResponseDTO(
                currentUser.getUserId(),
                currentUser.getNickname(),
                currentUser.getEmail(),
                currentUser.getAvatarUrl(),
                currentUser.getBio(),
                currentUser.getRegistrationTime(),
                currentUser.getStatus()
        );

        return ResponseEntity.ok(ApiResponse.success(profile, "User profile retrieved successfully."));
    }

    /**
     * 获取当前用户的动态内容
     * GET /user/me/content
     */
    @GetMapping("/me/content")
    public ResponseEntity<ApiResponse<Page<FeedItemDTO>>> getMyContent(
            @AuthenticationPrincipal User currentUser,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size
    ) {
        Pageable pageable = PageRequest.of(page, size);
        Page<FeedItemDTO> userFeed = feedService.getUserFeed(currentUser.getUserId(), pageable);
        return ResponseEntity.ok(ApiResponse.success(userFeed, "获取我的内容成功"));
    }



    /**
     * 获取指定用户的个人主页信息
     * GET /users/{id}/profile
     */
    @GetMapping("/{id}/profile")
    public ResponseEntity<ApiResponse<UserProfileDTO>> getUserProfile(
            @PathVariable Long id,
            // @AuthenticationPrincipal 可以是可选的，如果未登录，则为null
            @AuthenticationPrincipal @Nullable User currentUser,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size
    ) {
        Pageable pageable = PageRequest.of(page, size);
        Long currentUserId = (currentUser != null) ? currentUser.getUserId() : null;

        UserProfileDTO userProfile = userService.getUserProfile(id, currentUserId, pageable);

        return ResponseEntity.ok(ApiResponse.success(userProfile, "获取用户主页成功"));
    }


    /**
     * 更新当前用户的个人资料
     * PUT /user/me
     */
    @PutMapping("/updateMe")
    public ResponseEntity<ApiResponse<Object>> updateProfile(@RequestBody UserProfileUpdateRequestDTO request) {
        User currentUser = getCurrentAuthenticatedUser();
        User updatedUser = authService.updateProfile(currentUser.getUserId(), request);

        // 构建响应体，可以只返回消息和用户ID，或者返回完整的更新后资料
        // 根据你提供的响应示例，只返回消息和用户ID
        return ResponseEntity.ok(ApiResponse.success(
                new Object() { // 匿名内部类创建JSON响应
                    public String getMessage() { return "个人资料更新成功。"; }
                    public Long getUserId() { return updatedUser.getUserId(); }
                }, "个人资料更新成功。"));
    }

    /**
     * 获取我关注的人发布的内容
     * GET /users/me/following-feed
     */
    @GetMapping("/me/following-feed")
    public ResponseEntity<ApiResponse<Page<FeedItemDTO>>> getMyFollowingFeed(
            @AuthenticationPrincipal User currentUser,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size
    ) {
        Pageable pageable = PageRequest.of(page, size);

        // 1. 获取关注的用户ID列表
        List<Long> followingIds = followService.getFollowingUserIds(currentUser);

        // 2. 调用Feed服务获取信息流
        Page<FeedItemDTO> feedPage = feedService.getFollowingFeed(followingIds, pageable);

        return ResponseEntity.ok(ApiResponse.success(feedPage, "获取关注信息流成功"));
    }
    /**
     * 获取我关注的人的信息
     * GET /users/{id}/following
     */
    @GetMapping("/{id}/following")
    public ResponseEntity<ApiResponse<Page<FollowUserInfoDTO>>> getFollowingList(
            @PathVariable Long id,
            Pageable pageable,
            @AuthenticationPrincipal User currentUser) {
        User user = userRepository.findById(id).orElseThrow(() -> new CustomException("用户不存在", HttpStatus.NOT_FOUND));
        Page<FollowUserInfoDTO> followingList = followService.getFollowingList(user, pageable, currentUser);
        return ResponseEntity.ok(ApiResponse.success(followingList, "获取关注列表成功"));
    }

    /**
     * 获取指定用户的粉丝列表
     */
    @GetMapping("/{id}/followers")
    public ResponseEntity<ApiResponse<Page<FollowUserInfoDTO>>> getFollowerList(
            @PathVariable Long id,
            Pageable pageable,
            @AuthenticationPrincipal User currentUser) {
        User user = userRepository.findById(id).orElseThrow(() -> new CustomException("用户不存在", HttpStatus.NOT_FOUND));
        Page<FollowUserInfoDTO> followerList = followService.getFollowerList(user, pageable, currentUser);
        return ResponseEntity.ok(ApiResponse.success(followerList, "获取粉丝列表成功"));
    }


    /**
     * 获取当前用户的收藏列表
     * GET /users/me/collections
     */
    @GetMapping("/me/collections")
    public ResponseEntity<ApiResponse<Page<ArticleSummaryDTO>>> getMyCollections(
            @AuthenticationPrincipal User currentUser,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size
    ) {
        // 收藏列表通常按收藏时间倒序排列
        Pageable pageable = PageRequest.of(page, size, Sort.by("collectionTime").descending());
        Page<ArticleSummaryDTO> collections = collectionService.getUserCollections(currentUser, pageable);
        return ResponseEntity.ok(ApiResponse.success(collections, "获取收藏列表成功"));
    }
    @PostMapping("/forgot-password")
    public ResponseEntity<ApiResponse<String>> forgotPassword(@Valid @RequestBody ForgotPasswordRequestDTO request) {
        authService.forgotPassword(request);
        return ResponseEntity.ok(ApiResponse.success("密码重置说明已发送至您的邮箱/手机。", "Password reset instructions sent."));
    }

    @PatchMapping("/me/password")
    public ResponseEntity<ApiResponse<String>> updateMyPassword(
            @AuthenticationPrincipal User currentUser,
            @Valid @RequestBody PasswordUpdateRequestDTO request) {

        authService.updatePassword(currentUser.getUserId(), request.getOldPassword(), request.getNewPassword());

        return ResponseEntity.ok(ApiResponse.success("密码修改成功，请重新登录。", "Password updated successfully."));
    }


    /**
     * 重置密码 用户必须未登录
     * POST /reset-password
     */
    @PostMapping("/reset-password")
    public ResponseEntity<ApiResponse<String>> resetPassword(@Valid @RequestBody ResetPasswordRequestDTO request) {
        authService.resetPassword(request);
        return ResponseEntity.ok(ApiResponse.success("密码重置成功。", "Password reset successful."));
    }
}